#define _GNU_SOURCE
#include "daemon_sub_process.h"
#include "sys/wait.h"
#include "stdlib.h"
#include "unistd.h"
#include "sys/reboot.h"
#include "string.h"
#include "log.h"


/**
 * 初始化子进程 
 * 
 */
SubProcess  *sub_process_init(char *sub_cmd )
{
     SubProcess *sub_process=malloc(sizeof(  SubProcess));
     // 子进程命令
     sub_process->sub_cmd= malloc(strlen(sub_cmd))  ;
     strcpy(sub_process->sub_cmd,sub_cmd);
    // 子进程pid
     sub_process->pid=-1;
     // 子进程失败次数
     sub_process->failed_count=0;

     return sub_process;

}


/**
 * 检查并启动子进程
 * 
 *  1  判断 什么时候启动子进程 1 子进程从来没启动过 pid == -1 2 用waitpid检测子进程是否已经退出了    返回值 -1 重启子进程
 *  2  status 是否为-1  不是好死  计数 如果超过阈值 直接重启设备
 *  3  启动子进程 fork  execve
 **/
int sub_process_check_and_start(SubProcess *sub_process)
{
   //1  判断 什么时候启动子进程 1 子进程从来没启动过 pid == -1 2 用waitpid检测子进程是否已经退出了    返回值 -1 重启子进程
   int status = 0;
   if(sub_process->pid != -1 && waitpid(sub_process->pid,&status,WNOHANG) != -1){
    return 0; //好好的进程 
   }
   //2  之后的要么 是没有启动过 或者夭折的 
    if(status==-1)
    {
        sub_process->failed_count++;
         if(sub_process->failed_count >= MAX_FAILED_COUNT)
         {
            reboot(RB_AUTOBOOT);  //必须引用_GNU_SOURCE
         } 
    }
    // 3  重启子进程
    sub_process->pid = fork();
    if(sub_process->pid > 0)
    {        //父进程
        log_info("子进程%s 重启成功",sub_process->sub_cmd);
        return 0;
        
    }
    else if(sub_process->pid == 0)
    {
            //子进程
            char *args[] = { EXE_NAME,sub_process->sub_cmd,NULL};
            char *env[] = {NULL};
            int ret= execve(EXE_NAME,args,env);
            if(ret == -1)
            {
                log_error("子进程%s 重启失败",sub_process->sub_cmd);
                _exit(1);
            }
    }
    return 0;

}


/**
 * 停止子进程
 */

int sub_process_stop(SubProcess *sub_process)
{
    if(sub_process->pid <= 0)
    {
        return 0;
    }
    kill(sub_process->pid,SIGTERM);
    waitpid(sub_process->pid, NULL, WUNTRACED);
    log_info("子进程%s 停止成功",sub_process->sub_cmd);
}